package com.smsc.headend.connector.snmp.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.smsc.headend.common.utils.R;
import com.smsc.headend.connector.service.FeignAssetManagementService;
import com.smsc.headend.connector.snmp.service.SnmpService;
import com.smsc.headend.module.asset.entity.ComEntity;
import com.smsc.headend.module.asset.entity.Meter;
import com.smsc.headend.module.networkfeature.dto.DeviceNetworkFeatureDto;
import com.smsc.headend.module.networkfeature.entity.LogDcuNetworkFeature;
import com.smsc.headend.module.networkfeature.entity.LogMeterNetworkFeature;
import com.smsc.headend.module.networkfeature.mib.MibConstants;
import com.smsc.headend.module.networkfeature.util.SnmpUtil;
import lombok.extern.slf4j.Slf4j;
import org.snmp4j.util.TableEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.*;

/**
 * @author qinbin
 * @date 2022/8/3 15:41
 */
@Service
@Slf4j
public class SnmpServiceImpl implements SnmpService {

    @Autowired
    FeignAssetManagementService assetManagementService;

    @Override
    public R getNetworkFeature(Long dcuId) {
        ComEntity comEntity = assetManagementService.getComByDeviceId(dcuId);
        if (null == comEntity) {
            return R.error("com is not exist");
        }
        int i = comEntity.getIpAddress().indexOf(":");
        String host = comEntity.getIpAddress().substring(0, i);
        int port = 161;
        String community = assetManagementService.getPropertyValue("SNMP_COMMUNITY");
        if (StrUtil.isBlank(community)) {
            community = "willfar";
        }
        String portStr = assetManagementService.getPropertyValue("SNMP_PORT");
        if (StrUtil.isNotBlank(portStr)) {
            port = Integer.parseInt(portStr);
        }
        try {
            SnmpUtil snmpUtil = new SnmpUtil(host, port, community);
            Map<Integer, LogDcuNetworkFeature> dcuNetworkFeatureMap = new HashMap<>(16);
            Map<Integer, LogMeterNetworkFeature> meterNetworkFeatureMap = new HashMap<>(16);
            List<TableEvent> tableEvents = snmpUtil.snmpWalk(MibConstants.GATEWAY);
            translateData(dcuNetworkFeatureMap, meterNetworkFeatureMap, tableEvents, dcuId);
            log.debug("dcuNetworkFeatureMap.size={},dcuNetworkFeatureMap={}", dcuNetworkFeatureMap.size(), dcuNetworkFeatureMap.toString());
            log.debug("meterNetworkFeatureMap.size={},meterNetworkFeatureMap={}", meterNetworkFeatureMap.size(), meterNetworkFeatureMap.toString());
            DeviceNetworkFeatureDto deviceNetworkFeatureDto = new DeviceNetworkFeatureDto();
            if (CollUtil.isNotEmpty(dcuNetworkFeatureMap)) {
                deviceNetworkFeatureDto.setDcuNetworkFeatures(dcuNetworkFeatureMap);
            }
            if (CollUtil.isNotEmpty(meterNetworkFeatureMap)) {
                deviceNetworkFeatureDto.setMeterNetworkFeatures(meterNetworkFeatureMap);
            }
            return R.data(deviceNetworkFeatureDto);
        } catch (IOException e) {
            log.error("snmp error {}", e.getMessage());
            return R.error(e.getMessage());
        }
    }

    /**
     * 数据转换
     *
     * @param dcuNetworkFeatureMap
     * @param meterNetworkFeatureMap
     * @param tableEvents
     * @param dcuId
     */
    public void translateData(Map<Integer, LogDcuNetworkFeature> dcuNetworkFeatureMap, Map<Integer, LogMeterNetworkFeature> meterNetworkFeatureMap, List<TableEvent> tableEvents, Long dcuId) {
        for (TableEvent tableEvent : tableEvents) {
            if (null == tableEvent.getColumns()) {
                continue;
            }
            String oid = tableEvent.getColumns()[0].getOid().toString();
            String vbs = tableEvent.getColumns()[0].getVariable().toString();
            if (StrUtil.isNotEmpty(oid)) {
                Integer index = Integer.parseInt(oid.substring(oid.lastIndexOf(".") + 1));
                String oidHeader = oid.substring(0, oid.lastIndexOf("."));
                LogDcuNetworkFeature dcuNetworkFeature = dcuNetworkFeatureMap.get(index);
                LogMeterNetworkFeature meterNetworkFeature = meterNetworkFeatureMap.get(index);
                switch (oidHeader) {
                    case MibConstants.METER_SN:
                        if (null == meterNetworkFeature) {
                            meterNetworkFeature = new LogMeterNetworkFeature();
                        }
                        meterNetworkFeature.setMeterSn(vbs);
                        Meter meter = assetManagementService.getMeterByMfgSn(vbs);
                        if (null == meter) {
                            log.error("meter not exists! {}", vbs);
                            break;
                        }
                        meterNetworkFeature.setDeviceId(meter.getMeterId());
                        break;
                    case MibConstants.METER_LASTTRANSTIME:
                        if (null == meterNetworkFeature) {
                            meterNetworkFeature = new LogMeterNetworkFeature();
                        }
                        meterNetworkFeature.setLastTransTv(Long.parseLong(vbs));
                        break;
                    case MibConstants.METER_RFLATENCY:
                        if (null == meterNetworkFeature) {
                            meterNetworkFeature = new LogMeterNetworkFeature();
                        }
                        meterNetworkFeature.setLatency(Integer.parseInt(vbs));
                        break;
                    case MibConstants.METER_RFRSSI:
                        if (null == meterNetworkFeature) {
                            meterNetworkFeature = new LogMeterNetworkFeature();
                        }
                        meterNetworkFeature.setSignalStrength(Integer.parseInt(vbs));
                        break;
                    case MibConstants.METER_RFPACKETLOSS:
                        if (null == meterNetworkFeature) {
                            meterNetworkFeature = new LogMeterNetworkFeature();
                        }
                        meterNetworkFeature.setPacketSuccess(Double.parseDouble(vbs));
                        break;
                    case MibConstants.FANPUSHSTATISTIC_STATISTICTIME:
                        if (null == dcuNetworkFeature) {
                            dcuNetworkFeature = new LogDcuNetworkFeature();
                        }
                        dcuNetworkFeature.setStatisticTime(Long.parseLong(vbs));
                        break;
                    case MibConstants.FANPUSHSTATISTIC_TOTALPUSHPACKETNUM:
                        if (null == dcuNetworkFeature) {
                            dcuNetworkFeature = new LogDcuNetworkFeature();
                        }
                        dcuNetworkFeature.setTotalPushPacketNum(Long.parseLong(vbs));
                        break;
                    case MibConstants.FANPUSHSTATISTIC_LOSTPUSHPACKETNUM:
                        if (null == dcuNetworkFeature) {
                            dcuNetworkFeature = new LogDcuNetworkFeature();
                        }
                        dcuNetworkFeature.setLostPushPacketNum(Long.parseLong(vbs));
                        break;
                    default:
                        break;
                }
                if (null != dcuNetworkFeature) {
                    dcuNetworkFeature.setDeviceId(dcuId);
                    dcuNetworkFeatureMap.put(index, dcuNetworkFeature);
                }
                if (null != meterNetworkFeature) {
                    meterNetworkFeatureMap.put(index, meterNetworkFeature);
                }
            }
        }
    }
}
